﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data.OleDb;
using System.Data;
using System.IO;
using GISDataAdapter.Data.Object.IO.Structure;
using GISDataAdapter.Data.Type;

namespace GISDataAdapter.Data
{
    public class DbfFileLoader
    {
        /// <summary>
        /// 读取DBF文件内容
        /// </summary>
        /// <param name="fileNameList">DBF文件列表</param>
        /// <returns></returns>
        public List<DataTable> Load(List<string> fileNameList)
        {
            List<DataTable> resultCollection = new List<DataTable>();

            foreach (string fileName in fileNameList)
            {
                DataTable result = new DataTable();
                List<FieldInfo> listOfColumn = new List<FieldInfo>();

                byte[] dbf = File.ReadAllBytes(fileName);

                int yy = dbf[1];
                int mm = dbf[2];
                int dd = dbf[3];

                int rowCount = BitConverter.ToInt32(dbf, 4);
                int firstDataRecordPosition = BitConverter.ToInt16(dbf, 8);
                int firstValuePosition = -1;

                for (int i = 32; i < dbf.Length; i = i + 32)
                {
                    //0x0D 每32字节为1个列头信息，列头信息表中第一个字节值为0x0D时表示列头信息结束。
                    if (dbf[i] == 13)
                    {
                        firstValuePosition = i + 1;
                        break;
                    }

                    //获取列名称
                    string fieldName = Encoding.GetEncoding("GB2312").GetString(dbf, i, 10);
                    int nullIndex = fieldName.IndexOf('\0');

                    if (nullIndex > 0)
                                                                                                                                                                                                                                                                                                                          {
                        fieldName = fieldName.Substring(0, nullIndex);
                    }

                    FieldInfo fieldInfo = new FieldInfo();
                    fieldInfo.FieldName = fieldName;
                    fieldInfo.FieldDataType = (DataType)dbf[i + 11];
                    fieldInfo.FieldByteLength = dbf[i + 16];
                    listOfColumn.Add(fieldInfo);
                }

                foreach (FieldInfo columnInfo in listOfColumn)
                {
                    result.Columns.Add(columnInfo.FieldName);
                }

                #region get value

                int lineCount = 0;
                int columnCount = 0;
                object[] itemArray = new object[listOfColumn.Count];

                //不同类型的数据长度不一样
                for (int i = firstValuePosition; i < dbf.Length; i = i + 255)
                {
                    if (lineCount == rowCount)
                    {
                        break;
                    }

                    string value = Encoding.GetEncoding("GB2312").GetString(dbf, i, 255);
                    value = value.Trim();
                    itemArray[columnCount] = value;

                    if (columnCount == listOfColumn.Count - 1)
                    {
                        columnCount = 0;
                        DataRow row = result.NewRow();
                        row.ItemArray = itemArray;
                        lineCount++;
                        continue;
                    }

                    columnCount++;
                }

                #endregion

                resultCollection.Add(result);
            }

            return resultCollection;
        }
    }
}
